home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / sys / share / pcmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  10.1 KB  |  498 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)pcmain.c    3.1    93/06/28    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* main.c - MSDOS, OS/2, ST, Amiga, and NT NetHack */
  6.  
  7. #include "hack.h"
  8.  
  9. #ifndef NO_SIGNAL
  10. #include <signal.h>
  11. #endif
  12.  
  13. #include <ctype.h>
  14.  
  15. #if !defined(AMIGA) && !defined(GNUDOS)
  16. #include <sys\stat.h>
  17. #else
  18. # ifdef GNUDOS
  19. #include <sys/stat.h>
  20. # endif
  21. #endif
  22.  
  23. #if !defined(LATTICE)
  24. char orgdir[PATHLEN];
  25. #endif
  26.  
  27. #ifdef MFLOPPY
  28. struct finfo    zfinfo = ZFINFO;
  29. int i;
  30. #endif /* MFLOPPY */
  31.  
  32. #ifdef TOS
  33. boolean run_from_desktop = TRUE;    /* should we pause before exiting?? */
  34. # ifdef __GNUC__
  35. long _stksize = 16*1024;
  36. # endif
  37. #endif
  38.  
  39. #ifdef AMIGA
  40. extern int bigscreen;
  41. #endif
  42. #ifdef AMII_GRAPHICS
  43. extern unsigned short amii_initmap[8];
  44. #endif
  45.  
  46. static void FDECL(process_options,(int argc,char **argv));
  47.  
  48. int FDECL(main, (int,char **));
  49.  
  50. const char *classes = "ABCEHKPRSTVW";
  51. #ifdef    AMIGA
  52. void NDECL( preserve_icon );
  53. #endif
  54.  
  55. int
  56. main(argc,argv)
  57. int argc;
  58. char *argv[];
  59. {
  60.     register int fd;
  61.     register char *dir;
  62. #ifdef TOS
  63.     long clock_time;
  64.     if (*argv[0]) {            /* only a CLI can give us argv[0] */
  65.         hname = argv[0];
  66.         run_from_desktop = FALSE;
  67.     } else
  68. #endif
  69.         hname = "NetHack";    /* used for syntax messages */
  70.  
  71.     choose_windows(DEFAULT_WINDOW_SYS);
  72.  
  73. #if !defined(AMIGA) && !defined(GNUDOS)
  74.     /* Save current directory and make sure it gets restored when
  75.      * the game is exited.
  76.      */
  77.     if (getcwd(orgdir, sizeof orgdir) == NULL)
  78.         error("NetHack: current directory path too long");
  79. # ifndef NO_SIGNAL
  80.     signal(SIGINT, (SIG_RET_TYPE) exit);    /* restore original directory */
  81. # endif
  82. #endif /* !AMIGA && !GNUDOS */
  83.  
  84.     dir = getenv("NETHACKDIR");
  85.     if (dir == NULL)
  86.         dir = getenv("HACKDIR");
  87.     if (dir != NULL) {
  88.         Strcpy(hackdir, dir);
  89. #ifdef CHDIR
  90.         chdirx (dir, 1);
  91. #endif
  92.     }
  93. #if defined(AMIGA) && defined(CHDIR)
  94.     /*
  95.      * If we're dealing with workbench, change the directory.  Otherwise
  96.      * we could get "Insert disk in drive 0" messages. (Must be done
  97.      * before initoptions())....
  98.      */
  99.     if(argc == 0)
  100.         chdirx(HACKDIR, 1);
  101. #endif
  102.  
  103. #ifdef MFLOPPY
  104.     /* zero "fileinfo" array to prevent crashes on level change */
  105.     for (i = 0 ; i <= MAXLEVEL; i++) {
  106.         fileinfo[i] = zfinfo;
  107.     }
  108. #endif /* MFLOPPY */
  109. #ifdef AMIGA
  110.     ami_argc=argc;
  111.     ami_argv=argv;
  112. #endif
  113. #ifdef AMII_GRAPHICS
  114.     memcpy(flags.amii_curmap,amii_initmap,sizeof(flags.amii_curmap));
  115. #endif
  116.     initoptions();
  117.  
  118. #if defined(TOS) && defined(TEXTCOLOR)
  119.     if (flags.BIOS && flags.use_color)
  120.         set_colors();
  121. #endif
  122.     if (!hackdir[0])
  123. #if !defined(LATTICE) && !defined(AMIGA)
  124.         Strcpy(hackdir, orgdir);
  125. #else
  126.         Strcpy(hackdir, HACKDIR);
  127. #endif
  128.     if(argc > 1) {
  129.         if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  130.         /* avoid matching "-dec" for DECgraphics; since the man page
  131.          * says -d directory, hope nobody's using -desomething_else
  132.          */
  133.         argc--;
  134.         argv++;
  135.         dir = argv[0]+2;
  136.         if(*dir == '=' || *dir == ':') dir++;
  137.         if(!*dir && argc > 1) {
  138.             argc--;
  139.             argv++;
  140.             dir = argv[0];
  141.         }
  142.         if(!*dir)
  143.             error("Flag -d must be followed by a directory name.");
  144.         Strcpy(hackdir, dir);
  145.         } else
  146.  
  147.     /*
  148.      * Now we know the directory containing 'record' and
  149.      * may do a prscore().
  150.      */
  151.         if (!strncmp(argv[1], "-s", 2)) {
  152. #ifdef CHDIR
  153.         chdirx(hackdir,0);
  154. #endif
  155.         prscore(argc, argv);
  156.         exit(0);
  157.         }
  158.     }
  159.  
  160.     /*
  161.      * It seems you really want to play.
  162.      */
  163.     setrandom();
  164.  
  165. #ifdef TOS
  166.     if (comp_times((long)time(&clock_time)))
  167.         error("Your clock is incorrectly set!");
  168. #endif
  169.     u.uhp = 1;    /* prevent RIP on early quits */
  170.     u.ux = 0;    /* prevent flush_screen() */
  171.  
  172.     /* chdir shouldn't be called before this point to keep the
  173.      * code parallel to other ports which call gethdate just
  174.      * before here.
  175.      */
  176. #ifdef CHDIR
  177.     chdirx(hackdir,1);
  178. #endif
  179.  
  180.     process_options(argc, argv);
  181.  
  182. #ifdef AMIGA
  183.     ami_wbench_args();
  184. #endif
  185.     init_nhwindows();
  186. #ifdef MFLOPPY
  187.     set_lock_and_bones();
  188. # ifndef AMIGA
  189.     copybones(FROMPERM);
  190. # endif
  191. #endif
  192. #ifdef WIZARD
  193.     if (wizard)
  194.         Strcpy(plname, "wizard");
  195.     else
  196. #endif
  197.     if (!*plname)
  198.         askname();
  199.     plnamesuffix();        /* strip suffix from name; calls askname() */
  200.                 /* again if suffix was whole name */
  201.                 /* accepts any suffix */
  202. #ifndef MFLOPPY
  203.     Strcpy(lock,plname);
  204.     Strcat(lock,".99");
  205.     regularize(lock);    /* is this necessary? */
  206. #endif
  207.  
  208.     /* set up level 0 file to keep game state in */
  209.     /* this will have to be expanded to something like the
  210.      * UNIX/VMS getlock() to allow networked PCs in any case
  211.      */
  212.     fd = create_levelfile(0);
  213.     if (fd < 0) {
  214.         raw_print("Cannot create lock file");
  215.     } else {
  216.         hackpid = 1;
  217.         write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
  218.         close(fd);
  219.     }
  220. #ifdef MFLOPPY
  221.         fileinfo[0].where = ACTIVE;
  222. #endif
  223.  
  224.     /*
  225.      * Initialisation of the boundaries of the mazes
  226.      * Both boundaries have to be even.
  227.      */
  228.  
  229.     x_maze_max = COLNO-1;
  230.     if (x_maze_max % 2)
  231.         x_maze_max--;
  232.     y_maze_max = ROWNO-1;
  233.     if (y_maze_max % 2)
  234.         y_maze_max--;
  235.  
  236.     /*
  237.      *  Initialize the vision system.  This must be before mklev() on a
  238.      *  new game or before a level restore on a saved game.
  239.      */
  240.     vision_init();
  241.  
  242.     display_gamewindows();
  243.  
  244.     set_savefile_name();
  245.  
  246.     if (
  247. #ifdef MFLOPPY
  248. # ifdef AMIGA
  249.         (FromWBench || saveDiskPrompt(1)) &&
  250. # else
  251.         saveDiskPrompt(1) &&
  252. # endif
  253. #endif /* MFLOPPY */
  254.         ((fd = open_savefile()) >= 0) &&
  255.        /* if not up-to-date, quietly unlink file via false condition */
  256.        (uptodate(fd) || ((void)close(fd), delete_savefile()))) {
  257. #ifdef WIZARD
  258.         /* Since wizard is actually flags.debug, restoring might
  259.          * overwrite it.
  260.          */
  261.         boolean remember_wiz_mode = wizard;
  262. #endif
  263. #ifndef NO_SIGNAL
  264.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  265. #endif
  266. #ifdef NEWS
  267.         if(flags.news){
  268.             display_file(NEWS, FALSE);
  269.             flags.news = FALSE;
  270.         }
  271. #endif
  272.         pline("Restoring save file...");
  273.         mark_synch();    /* flush output */
  274.  
  275.         if(!dorecover(fd))
  276.             goto not_recovered;
  277. #ifdef WIZARD
  278.         if(!wizard && remember_wiz_mode) wizard = TRUE;
  279. #endif
  280.         pline("Hello %s, welcome back to NetHack!", plname);
  281.         check_special_room(FALSE);
  282.  
  283. #ifdef EXPLORE_MODE
  284.         if (discover)
  285.             You("are in non-scoring discovery mode.");
  286. #endif
  287. #if defined(EXPLORE_MODE) || defined(WIZARD)
  288.         if (discover || wizard) {
  289.             if(yn("Do you want to keep the save file?") == 'n'){
  290.                 (void) delete_savefile();
  291.             }
  292. #ifdef AMIGA
  293.             else
  294.                 preserve_icon();
  295. #endif
  296.         }
  297. #endif
  298.         flags.move = 0;
  299.     } else {
  300. not_recovered:
  301.         player_selection();
  302.         newgame();
  303.         /* give welcome message before pickup messages */
  304.         pline("Hello %s, welcome to NetHack!", plname);
  305. #ifdef EXPLORE_MODE
  306.         if (discover)
  307.             You("are in non-scoring discovery mode.");
  308. #endif
  309.         flags.move = 0;
  310.         set_wear();
  311.         pickup(1);
  312.         read_engr_at(u.ux,u.uy);
  313.     }
  314.     
  315.     flags.moonphase = phase_of_the_moon();
  316.     if(flags.moonphase == FULL_MOON) {
  317.         You("are lucky!  Full moon tonight.");
  318.         change_luck(1);
  319.     } else if(flags.moonphase == NEW_MOON) {
  320.         pline("Be careful!  New moon tonight.");
  321.     }
  322.     if(flags.friday13 = friday_13th()) {
  323.         pline("Watch out!  Bad things can happen on Friday the 13th.");
  324.         change_luck(-1);
  325.     }
  326.  
  327.     initrack();
  328. #ifndef NO_SIGNAL
  329.     (void) signal(SIGINT, SIG_IGN);
  330. #endif
  331. #ifdef OS2
  332.     gettty(); /* somehow ctrl-P gets turned back on during startup ... */
  333. #endif
  334.  
  335.     moveloop();
  336.     return 0;
  337. }
  338.  
  339. static void
  340. process_options(argc, argv)
  341. int argc;
  342. char *argv[];
  343. {
  344.     /*
  345.      * Process options.
  346.      */
  347.     while(argc > 1 && argv[1][0] == '-'){
  348.         argv++;
  349.         argc--;
  350.         switch(argv[0][1]){
  351. #if defined(WIZARD) || defined(EXPLORE_MODE)
  352. # ifndef EXPLORE_MODE
  353.         case 'X':
  354. # endif
  355.         case 'D':
  356. # ifdef WIZARD
  357.             /* Must have "name" set correctly by NETHACK.CNF,
  358.              * NETHACKOPTIONS, or -u
  359.              * before this flag to enter wizard mode. */
  360. #  ifdef KR1ED
  361.             if(!strcmp(plname, WIZARD_NAME)) {
  362. #  else
  363.             if(!strcmp(plname, WIZARD)) {
  364. #  endif
  365.                 wizard = TRUE;
  366.                 break;
  367.             }
  368.             /* otherwise fall thru to discover */
  369. # endif
  370. # ifdef EXPLORE_MODE
  371.         case 'X':
  372.             discover = TRUE;
  373. # endif
  374.             break;
  375. #endif
  376. #ifdef NEWS
  377.         case 'n':
  378.             flags.news = FALSE;
  379.             break;
  380. #endif
  381.         case 'u':
  382.             if(argv[0][2])
  383.               (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  384.             else if(argc > 1) {
  385.               argc--;
  386.               argv++;
  387.               (void) strncpy(plname, argv[0], sizeof(plname)-1);
  388.             } else
  389.                 raw_print("Player name expected after -u");
  390.             break;
  391. #ifndef AMIGA
  392.         case 'I':
  393.         case 'i':
  394.             if (!strncmpi(argv[0]+1, "IBM", 3))
  395.                 switch_graphics(IBM_GRAPHICS);
  396.             break;
  397.         /*  case 'D': */
  398.         case 'd':
  399.             if (!strncmpi(argv[0]+1, "DEC", 3))
  400.                 switch_graphics(DEC_GRAPHICS);
  401.             break;
  402. #endif
  403. #ifdef MFLOPPY
  404. # ifndef AMIGA
  405.         /* Player doesn't want to use a RAM disk
  406.          */
  407.         case 'r':
  408.             ramdisk = FALSE;
  409.             break;
  410. # endif
  411. #endif
  412. #ifdef AMIGA
  413.             /* interlaced and non-interlaced screens */
  414.         case 'L':
  415.             bigscreen = 1;
  416.             break;
  417.         case 'l':
  418.             bigscreen = -1;
  419.             break;
  420. #endif
  421.         default:
  422.             if (index(classes, toupper(argv[0][1]))) {
  423.                 /* allow -T for Tourist, etc. */
  424.                 (void) strncpy(pl_character, argv[0]+1,
  425.                            sizeof(pl_character)-1);
  426.                 break;
  427.             } else raw_printf("\nUnknown switch: %s", argv[0]);
  428.         case '?':
  429.             (void) printf(
  430.             "\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...",
  431.             hname, classes);
  432.             (void) printf("\n       or");
  433.             (void) printf("\n       %s [-d dir] [-u name] [-[%s]]",
  434.             hname, classes);
  435. #if defined(WIZARD) || defined(EXPLORE_MODE)
  436.             (void) printf(" [-[DX]]");
  437. #endif
  438. #ifdef NEWS
  439.             (void) printf(" [-n]");
  440. #endif
  441. #ifndef AMIGA
  442.             (void) printf(" [-I] [-i] [-d]");
  443. #endif
  444. #ifdef MFLOPPY
  445. # ifndef AMIGA
  446.             (void) printf(" [-r]");
  447. # endif
  448. #endif
  449. #ifdef AMIGA
  450.             (void) printf(" [-[lL]]");
  451. #endif
  452.             putchar('\n');
  453.             exit(0);
  454.         }
  455.     }
  456. }
  457.  
  458. #ifdef CHDIR
  459. void
  460. chdirx(dir, wr)
  461. char *dir;
  462. boolean wr;
  463. {
  464. #ifdef AMIGA
  465.     static char thisdir[] = "";
  466. #else
  467.     static char thisdir[] = ".";
  468. #endif
  469.     if(dir && chdir(dir) < 0) {
  470.         error("Cannot chdir to %s.", dir);
  471.     }
  472.  
  473.     /* Change the default drive as well.
  474.      */
  475. #ifndef AMIGA
  476.     chdrive(dir);
  477. #endif
  478.  
  479.     /* warn the player if we can't write the record file */
  480.     /* perhaps we should also test whether . is writable */
  481.     /* unfortunately the access system-call is worthless */
  482.     if (wr) check_recordfile(dir ? dir : thisdir);
  483. }
  484. #endif /* CHDIR */
  485.  
  486. #ifdef  PORT_HELP
  487. # if defined(MSDOS) || defined(WIN32)
  488. void
  489. port_help()
  490. {
  491.     /* display port specific help file */
  492.     display_file( PORT_HELP, 1 );
  493. }
  494. # endif /* MSDOS || WIN32 */
  495. #endif /* PORT_HELP */
  496.  
  497. /*pcmain.c*/
  498.